//
//  FMResourceLoader.m
//  FMRemotePlayer
//
//  Created by appbanana on 2017/3/12.
//  Copyright © 2017年 appbanana. All rights reserved.
//

#import "FMResourceLoader.h"
#import "FMRemotePlayerFile.h"
#import "FMResouceDownLoader.h"
#import "NSURL+Extension.h"

@interface FMResourceLoader ()<FMResouceDownLoaderDelegate>

@property (nonatomic, strong) FMResouceDownLoader *downLoader;

@property (nonatomic, strong) NSMutableArray<AVAssetResourceLoadingRequest *> *loadRequests;

@end

@implementation FMResourceLoader

- (BOOL)resourceLoader:(AVAssetResourceLoader *)resourceLoader shouldWaitForLoadingOfRequestedResource:(AVAssetResourceLoadingRequest *)loadingRequest{
    [self.loadRequests addObject:loadingRequest];
    //NSURL *url = self.loadRequests.firstObject.request.URL;
    NSURL *url = [loadingRequest.request.URL httpURL];

    //1.首先根据请求的资源地址，判断本地缓存路径有没有 如果有的话直接加载 return
    // 1.1 拿到拼接路径
    // 1.2 判断路径是否存在
   BOOL isExists = [FMRemotePlayerFile fileExistsWithAudioURL:url];
    if (isExists) {
        [self handleLoadingRequest:loadingRequest];
        //[self handleRequestWithLoadingRequest:loadingRequest];
        return YES;
    }
    
    long long requestedOffset = loadingRequest.dataRequest.requestedOffset;
    //2.本地缓存路径没有 判断是否有开始下载过 如果没有下载 下载 return
    if (self.downLoader.loadSize == 0) {
        //去下载
        [self.downLoader downLoadWithUrl:url offset:0];
        return YES;
    }

    
    //3.如果当前正在下载，还是要判断 是否要重新下载
    // 3.1 当请求的节点小于下载的节点 重新下载
    // 3.2 当请求的节点 大于 下载的节点+ 下载的长度 + 容错区间（1000）重新下载 return
    if (requestedOffset < self.downLoader.offset || requestedOffset > self.downLoader.offset + self.downLoader.loadSize + 1000) {
//notice 注意事项  offset 之前的offset我写的不是0 我之前写的是requestedOffset
        [self.downLoader downLoadWithUrl:url offset:0];
        return YES;
    }
    
    //4.当前正在下载 不需要重新下载
    [self handleAllLoadingRequests];

    
    return YES;
}


- (void)resourceLoader:(AVAssetResourceLoader *)resourceLoader didCancelLoadingRequest:(AVAssetResourceLoadingRequest *)loadingRequest{
    [loadingRequest finishLoading];
}

- (void)handleLoadingRequest:(AVAssetResourceLoadingRequest *)loadingRequest{
    //    NSData *data = [NSData dataWithContentsOfFile:@"/Users/JQC/Desktop/123.mp3"];
    //    下面这个方法比上个方法好 上个方法会把对应的视频 音频问价直接加载到内存中,会造成内存的飙升,而下面这方法会把映射到数据一段一段的地址上
    NSURL *url = [loadingRequest.request.URL httpURL];

    loadingRequest.contentInformationRequest.contentType = [FMRemotePlayerFile contentTypeWithURL:url];
    loadingRequest.contentInformationRequest.contentLength = [FMRemotePlayerFile fileSizeWithAudioURL:url];
    //这属性是控制把请求玩的一小段一小段的音频文件传给他 no的话表明是等请求完后才把资源文件传给他 这样体验效果不好
    loadingRequest.contentInformationRequest.byteRangeAccessSupported = YES;
    
//notice 注意事项
    //妈的这搞了我好久 我之前把路径地址写错了 我之前的是tempAudioFilePath地址
    NSString *filePath = [FMRemotePlayerFile cacheAudioFilePath:url];
    NSData *data =[NSData dataWithContentsOfFile:filePath options:NSDataReadingMappedIfSafe error:nil];
    
    long long requestOffset = loadingRequest.dataRequest.requestedOffset;
    long long requestedLength = loadingRequest.dataRequest.requestedLength;
    NSData *subData = [data subdataWithRange:NSMakeRange(requestOffset, requestedLength)];
    [loadingRequest.dataRequest respondWithData:subData];
    [loadingRequest finishLoading];
}



- (void)handleAllLoadingRequests{
    
    NSMutableArray *deleteRequests = [NSMutableArray array];

    for (AVAssetResourceLoadingRequest *loadRequest in self.loadRequests) {
        
        if ([loadRequest isFinished] || [loadRequest isCancelled]) {
            [deleteRequests addObject:loadRequest];
            break ;
        }
        loadRequest.contentInformationRequest.contentType = self.downLoader.contentType;
        loadRequest.contentInformationRequest.contentLength = self.downLoader.totalSize;
        loadRequest.contentInformationRequest.byteRangeAccessSupported = YES;
        
        NSURL *url = self.downLoader.url;
        NSData *data = [NSData dataWithContentsOfFile:[FMRemotePlayerFile tempAudioFilePath:url] options:NSDataReadingMappedIfSafe error:nil];
        if (data.length == 0) {
            data = [NSData dataWithContentsOfFile:[FMRemotePlayerFile cacheAudioFilePath:url] options:NSDataReadingMappedIfSafe error:nil];
        }
        if (data.length == 0) {
            return ;
        }
        long long requestedOffset = loadRequest.dataRequest.requestedOffset;
        if (loadRequest.dataRequest.currentOffset != 0) {
            requestedOffset = loadRequest.dataRequest.currentOffset;
        }
        long long requestedLength = loadRequest.dataRequest.requestedLength;
        
        long long responseOffset = requestedOffset - self.downLoader.offset;
        long long responseLength = MIN(requestedLength, self.downLoader.offset + self.downLoader.loadSize - requestedOffset);

        NSData *subData = [data subdataWithRange:NSMakeRange(responseOffset, responseLength)];
        [loadRequest.dataRequest respondWithData:subData];
        if (responseLength == requestedLength) {
            [loadRequest finishLoading];
            [deleteRequests addObject:loadRequest];
        }
    }
    
    [self.loadRequests removeObjectsInArray:deleteRequests];
    
}




#pragma mark-----FMResouceDownLoaderDelegate-----
- (void)receiveNewData{
    [self handleAllLoadingRequests];

}
















#pragma mark------seter geter-----
- (FMResouceDownLoader *)downLoader{
    if (!_downLoader) {
        _downLoader = [[FMResouceDownLoader alloc] init];
        _downLoader.delegate = self;
    }
    return _downLoader;
}

- (NSMutableArray<AVAssetResourceLoadingRequest *> *)loadRequests{
    if (!_loadRequests) {
        _loadRequests = [NSMutableArray arrayWithCapacity:1];
    }
    return _loadRequests;
}

/*
 <AVAssetResourceLoadingRequest: 0x60800000e830, URL request = <NSMutableURLRequest: 0x6000000060e0> { URL: fm://audio.xmcdn.com/group22/M0B/60/85/wKgJM1g1g0ShoPalAJiI5nj3-yY200.m4a }, request ID = 1, content information request = <AVAssetResourceLoadingContentInformationRequest: 0x600000006120, content type = "(null)", content length = 0, byte range access supported = NO, disk caching permitted = NO, renewal date = (null)>, data request = <AVAssetResourceLoadingDataRequest: 0x608000005000, requested offset = 0, requested length = 2, requests all data to end of resource = NO, current offset = 0>>
 2017-03-12 21:18:01.281
 */

@end
